package com.surpassun.emall.util;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PasswordUtil {
	
	private static Logger _log = LoggerFactory.getLogger(PasswordUtil.class);
	
	public static String encrypt(String clearTextPwd) {
		try {
			return encodePassword(clearTextPwd, "F8N.q_u0".getBytes());
		} catch (NoSuchAlgorithmException e) {
			_log.error("Error while generating password", e);
			return null;
		}
	}
	
	private static String encodePassword(String clearTextPwd, byte[] saltBytes) throws NoSuchAlgorithmException {

		byte[] clearTextPwdBytes = clearTextPwd.getBytes(Charset.defaultCharset());

		// Create a byte array of salt bytes appeneded to password bytes

		byte[] pwdPlusSalt = new byte[clearTextPwdBytes.length + saltBytes.length];

		System.arraycopy(clearTextPwdBytes, 0, pwdPlusSalt, 0, clearTextPwdBytes.length);

		System.arraycopy(saltBytes, 0, pwdPlusSalt, clearTextPwdBytes.length, saltBytes.length);

		// Digest byte array

		MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1");
		

		byte[] pwdPlusSaltHash = sha1Digest.digest(pwdPlusSalt);

		// Appends salt bytes to the SHA-1 digest.

		byte[] digestPlusSalt = new byte[pwdPlusSaltHash.length + saltBytes.length];

		System.arraycopy(pwdPlusSaltHash, 0, digestPlusSalt, 0, pwdPlusSaltHash.length);

		System.arraycopy(saltBytes, 0, digestPlusSalt, pwdPlusSaltHash.length, saltBytes.length);

		// Base64 encode and format string

		return encode(digestPlusSalt);
	}
	
	private static char getChar(int sixbit) {
		if (sixbit >= 0 && sixbit <= 25) {
			return (char)(65 + sixbit);
		}

		if (sixbit >= 26 && sixbit <= 51) {
			return (char)(97 + (sixbit - 26));
		}

		if (sixbit >= 52 && sixbit <= 61) {
			return (char)(48 + (sixbit - 52));
		}

		if (sixbit == 62) {
			return '+';
		}

		return sixbit != 63 ? '?' : '/';
	}

	private static String encode(byte raw[]) {
		StringBuilder encoded = new StringBuilder();

		for (int i = 0; i < raw.length; i += 3) {
			encoded.append(encodeBlock(raw, i));
		}

		return encoded.toString();
	}

	private static char[] encodeBlock(byte raw[], int offset) {
		int block = 0;
		int slack = raw.length - offset - 1;
		int end = slack < 2 ? slack : 2;

		for (int i = 0; i <= end; i++) {
			byte b = raw[offset + i];

			int neuter = b >= 0 ? ((int) (b)) : b + 256;
			block += neuter << 8 * (2 - i);
		}

		char base64[] = new char[4];

		for (int i = 0; i < 4; i++) {
			int sixbit = block >>> 6 * (3 - i) & 0x3f;
			base64[i] = getChar(sixbit);
		}

		if (slack < 1) {
			base64[2] = '=';
		}

		if (slack < 2) {
			base64[3] = '=';
		}

		return base64;
	}
}
